home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / others / ole_101.zip / SCHMOO.ZIP / OLEOBJ.C < prev    next >
C/C++ Source or Header  |  1992-04-13  |  15KB  |  549 lines

  1. /*
  2.  * OLEOBJ.C
  3.  *
  4.  * Contains all callback functions in the OLEOBJECTVTBL struture:
  5.  *      ObjDoVerb
  6.  *      ObjEnumFormats
  7.  *      ObjGetData
  8.  *      ObjQueryProtocol
  9.  *      ObjRelease
  10.  *      ObjSetBounds
  11.  *      ObjSetColorScheme
  12.  *      ObjSetData
  13.  *      ObjSetTargetDevice
  14.  *      ObjShow
  15.  *
  16.  * There are additional callbacks in the OLEOBJECTVTBL but those are
  17.  * expressly for object handler DLLs which are not covered here.
  18.  *
  19.  * Also contains PObjectAllocate, a constructor for the object.
  20.  *
  21.  * Copyright(c) Microsoft Corp. 1992 All Rights Reserved
  22.  *
  23.  */
  24.  
  25.  
  26. #ifdef MAKEOLESERVER
  27.  
  28. #include <windows.h>
  29. #include <ole.h>
  30. #include "schmoo.h"
  31. #include "oleglobl.h"
  32. #include "oleinst.h"    //OBJVERB_* defines for ObjDoVerb
  33.  
  34. /*
  35.  * PObjectAllocate
  36.  *
  37.  * Purpose:
  38.  *  Allocates a SCHMOOOBJECT structure and sets the defaults in its fields.
  39.  *  Used from DocGetObject.
  40.  *
  41.  * Parameters:
  42.  *  pVtblObj        LPOLESERVERDOCVTBL used to initialize the pvtbl field.
  43.  *
  44.  * Return Value:
  45.  *  LPSCHMOOOBJECT  Pointer to the allocated structure in local memory.
  46.  *                  The hMem field will contain a handle to the structure
  47.  *                  to pass to LocalFree.
  48.  */
  49.  
  50. LPSCHMOOOBJECT FAR PASCAL PObjectAllocate(LPOLEOBJECTVTBL pVtblObj)
  51.     {
  52.     HANDLE          hMem;
  53.     LPSCHMOOOBJECT  pObj;
  54.  
  55.     hMem=LocalAlloc(LPTR, sizeof(SCHMOOOBJECT));
  56.     pObj=(LPSCHMOOOBJECT)(PSTR)hMem;
  57.  
  58.     //Initialize the object.
  59.     pObj->hMem=hMem;
  60.     pObj->pvtbl=pVtblObj;
  61.     pObj->fRelease=TRUE;
  62.  
  63.     return pObj;
  64.     }
  65.  
  66.  
  67.  
  68.  
  69. /*
  70.  * ObjDoVerb
  71.  *
  72.  * Purpose:
  73.  *  Performs actions on an object when the user opens an object
  74.  *  according to the verb given.
  75.  *
  76.  * Parameters:
  77.  *  pObj            LPSCHMOOOBJECT specifying the object affected.
  78.  *  iVerb           WORD index to the verb chosen, zero based.
  79.  *  fShow           BOOL--TRUE if the application should show
  80.  *                  itself with ShowWindow.  FALSE means no change.
  81.  *  fFocus          BOOL--TRUE if the server should get the focus.
  82.  *
  83.  * Return Value:
  84.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  85.  */
  86.  
  87. OLESTATUS FAR PASCAL ObjDoVerb(LPSCHMOOOBJECT pObj, WORD iVerb,
  88.                                BOOL fShow, BOOL fFocus)
  89.     {
  90.  
  91.     /*
  92.      * 1.   Execute the verb.
  93.      *        a.  For a 'Play' verb, a server does not generally show
  94.      *            its window or affect the focus.
  95.      *
  96.      *        b.  For an 'Edit' verb, show the server's window and the
  97.      *            object if fShow is TRUE, and take the focus if fFocus
  98.      *            is TRUE.  An ideal way to accomplish this is to call
  99.      *            the ObjShow method through the OLEOBJECTVTBL since that
  100.      *            method will handle showing the object and taking the
  101.      *            focus itself.
  102.      *
  103.      *        c.  An 'Open' verb is not clearly defined; depending on the
  104.      *            application it may mean the same as 'Play' or 'Edit.'
  105.      *            The Schmoo server, if it had an 'Open' verb, would treat
  106.      *            it like 'Edit.'
  107.      *
  108.      * 2.  Return OLE_OK if the verb was successfully executed, otherwise
  109.      *     OLE_ERROR_DOVERB.
  110.      */
  111.  
  112.     switch (iVerb)
  113.         {
  114.         case OBJVERB_EDIT:
  115.             /*
  116.              * On edit, simply show yourself and expect a SetData.
  117.              * Best strategy is to use the Show method for this
  118.              * object if necessary, reducing redundancy.
  119.              */
  120.             if (fShow)
  121.                 return (pObj->pvtbl->Show)((LPOLEOBJECT)pObj, fShow);
  122.  
  123.             //Return OLE_OK
  124.             break;
  125.  
  126.  
  127.         case OBJVERB_PLAY:
  128.             //Unsupported at this time.
  129.             return OLE_ERROR_DOVERB;
  130.  
  131.         default:
  132.             return OLE_ERROR_DOVERB;
  133.         }
  134.  
  135.     return OLE_OK;
  136.     }
  137.  
  138.  
  139.  
  140.  
  141.  
  142. /*
  143.  * ObjEnumFormats
  144.  *
  145.  * Purpose:
  146.  *  Requests the server to produce the 'next' supported clipboard
  147.  *  format.  Each format is returned in sequence until the terminator
  148.  *  (a NULL) is returned.
  149.  *
  150.  * Parameters:
  151.  *  pObj            LPSCHMOOOBJECT specifying the object affected.
  152.  *  cf              WORD the last clipboard format returned by this
  153.  *                  function.  0 indicates the first.
  154.  *
  155.  * Return Value:
  156.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  157.  */
  158.  
  159. OLECLIPFORMAT FAR PASCAL ObjEnumFormats(LPSCHMOOOBJECT pObj, WORD cf)
  160.     {
  161.     /*
  162.      * 1.   Depending on cf, return the 'next' clipboard format in which
  163.      *      the server can render the object's data.
  164.      * 2.   If there are no more supported formats after the format in cf,
  165.      *      return NULL.
  166.      *
  167.      * We must use multiple if's instead of a switch statement because
  168.      * all the cf* values are not constants.
  169.      */
  170.  
  171.     if (0==cf)
  172.        return pOLE->cfNative;
  173.  
  174.     if (pOLE->cfNative==cf)
  175.        return pOLE->cfOwnerLink;
  176.  
  177.     if (pOLE->cfOwnerLink==cf)
  178.        return CF_METAFILEPICT;
  179.  
  180.     if (CF_METAFILEPICT==cf)
  181.        return CF_BITMAP;
  182.  
  183.     if (CF_BITMAP==cf)
  184.        return pOLE->cfObjectLink;
  185.  
  186.     //This IF is here just to be explicit.
  187.     if (pOLE->cfObjectLink==cf)
  188.        return NULL;
  189.  
  190.     return NULL;
  191.     }
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198. /*
  199.  * ObjGetData
  200.  *
  201.  * Purpose:
  202.  *  Retrieves data from the object in a specified format, where the
  203.  *  server should allocate memory (GlobalAlloc with GMEM_DDESHARE),
  204.  *  fill the memory, and return the handle.
  205.  *
  206.  * Parameters:
  207.  *  pObj            LPSCHMOOOBJECT specifying the object affected.
  208.  *  cf              WORD format to return data in, may be "Native."
  209.  *  phData          LPHANDLE in which to store the allocated handle.
  210.  *
  211.  * Return Value:
  212.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  213.  */
  214.  
  215. OLESTATUS FAR PASCAL ObjGetData(LPSCHMOOOBJECT pObj, WORD cf, LPHANDLE phData)
  216.     {
  217.     HANDLE              hMem;
  218.  
  219.     /*
  220.      * 1.   Allocate the requested data throguh GlobalAlloc (with
  221.      *      GMEM_MOVEABLE and GMEM_DDESHARE).  The exception is data for
  222.      *      CF_BITMAP which uses a call like CreateBitmap.
  223.      * 2.   Lock and fill the memory with the appropriate data.
  224.      * 3.   Unlock the memory and store the handle in *phData.
  225.      * 4.   Return OLE_OK if successful, OLE_ERROR_MEMORY otherwise.
  226.      */
  227.  
  228.     //Return Native, metafile, or bitmap as requested.
  229.     if (pOLE->cfNative==cf)
  230.         hMem=HGetPolyline(pGlob->hWndPolyline);
  231.  
  232.     if (CF_METAFILEPICT==cf)
  233.         hMem=HGetMetafilePict(pGlob->hWndPolyline);
  234.  
  235.     if (CF_BITMAP==cf)
  236.         hMem=HGetBitmap(pGlob->hWndPolyline);
  237.  
  238.  
  239.     //Use filename
  240.     if (pOLE->cfObjectLink==cf)
  241.          hMem=HLinkConstruct(rgpsz[IDS_CLASSSCHMOO], "", "");
  242.  
  243.     /*
  244.      * Even though this is exactly like ObjectLink, this is coded as
  245.      * a separate case just in case it changes in the future.
  246.      */
  247.     if (pOLE->cfOwnerLink==cf)
  248.         hMem=HLinkConstruct(rgpsz[IDS_CLASSSCHMOO], "", "");
  249.  
  250.  
  251.     if (NULL==hMem)
  252.         return OLE_ERROR_MEMORY;
  253.  
  254.     *phData=hMem;
  255.     return OLE_OK;
  256.     }
  257.  
  258.  
  259.  
  260.  
  261.  
  262. /*
  263.  * ObjQueryProtocol
  264.  *
  265.  * Purpose:
  266.  *  Returns a pointer to an SCHMOOOBJECT with the appropriate VTBL for
  267.  *  the protocol, either StdFileEditing or StdExecute.  Returns NULL
  268.  *  if that protocol is not supported.
  269.  *
  270.  * Parameters:
  271.  *  pObj            LPSCHMOOOBJECT specifying the object affected.
  272.  *  pszProtocol     LPSTR, the protocol name.
  273.  *
  274.  * Return Value:
  275.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  276.  */
  277.  
  278. LPVOID FAR PASCAL ObjQueryProtocol(LPSCHMOOOBJECT pObj, LPSTR pszProtocol)
  279.     {
  280.  
  281.     /*
  282.      * 1.   If the protocol in pszProtocol is supported, return a pointer
  283.      *      to an object that contains an appropriate VTBL fot that protocol,
  284.      *      such as the pObj passed to this method.
  285.      * 2.   If the protocol is not supported, return NULL.
  286.      */
  287.  
  288.     //Check if OLESVR is asking for "StdFileEditing"
  289.     if (0==lstrcmp(pszProtocol, rgpsz[IDS_STDFILEEDITING]))
  290.         return (LPVOID)pObj;
  291.  
  292.     return (LPVOID)NULL;
  293.     }
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300. /*
  301.  * ObjRelease
  302.  *
  303.  * Purpose:
  304.  *  Notifies a server that is can free any resources associated with an
  305.  *  object.
  306.  *
  307.  * Parameters:
  308.  *  pObj            LPSCHMOOOBJECT specifying the object affected.
  309.  *
  310.  * Return Value:
  311.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  312.  */
  313.  
  314. OLESTATUS FAR PASCAL ObjRelease(LPSCHMOOOBJECT pObj)
  315.     {
  316.     /*
  317.      * 1.   Free any resources allocated for this object, but
  318.      *      DO NOT free the SCHMOOOBJECT structure itself if you reference
  319.      *      it any more.
  320.      * 2.   Set a flag to indicate that Release has been called.
  321.      * 3.   NULL any saved LPOLECLIENT stores in the OLEOBJECT structure.
  322.      * 4.   Return OLE_OK if successful, OLE_ERROR_GENERIC otherwise.
  323.      *
  324.      * Do not use the Release method to free the memory containing
  325.      * the object since you still need to use its pClient and fRelease.
  326.      * This method simply notifies the object that no one is using it
  327.      * anymore so we don't try to send notifications.
  328.      */
  329.  
  330.     pObj->fRelease=TRUE;
  331.     pObj->pClient=NULL;
  332.     return OLE_OK;
  333.     }
  334.  
  335.  
  336.  
  337.  
  338.  
  339. /*
  340.  * ObjSetBounds
  341.  *
  342.  * Purpose:
  343.  *  Specifies a new boundary rectangle for the object in MM_HIMETRIC
  344.  *  units.  Only useful for embedded objects since a linked object
  345.  *  depends on the file loaded.
  346.  *
  347.  * Parameters:
  348.  *  pObj            LPSCHMOOOBJECT specifying the object affected.
  349.  *  pRect           LPRECT containing the new bounds.
  350.  *
  351.  * Return Value:
  352.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  353.  */
  354.  
  355. OLESTATUS FAR PASCAL ObjSetBounds(LPSCHMOOOBJECT pObj, LPRECT pRect)
  356.     {
  357.     //Unused in OLE1.x
  358.     return OLE_OK;
  359.     }
  360.  
  361.  
  362.  
  363.  
  364. /*
  365.  * ObjSetColorScheme
  366.  *
  367.  * Purpose:
  368.  *  Provides a color scheme that the client application recommends for
  369.  *  rendering graphical data.
  370.  *
  371.  * Parameters:
  372.  *  pDoc            LPSCHMOOOBJECT specifying the object affected.
  373.  *  pPal            LPLOGPALETTE describing the recommended palette.
  374.  *
  375.  * Return Value:
  376.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  377.  */
  378.  
  379. OLESTATUS FAR PASCAL ObjSetColorScheme(LPSCHMOOOBJECT pObj, LPLOGPALETTE pPal)
  380.     {
  381.     /*
  382.      * Servers are not required to use this palette.  The LPLOGPALETTE
  383.      * only is a convenient structure to contain the color scheme; IT DOES
  384.      * not REPRESENT A PALETTE IN STRICT TERMS!  Do NOT call CreatePalette
  385.      * and try to realize it.
  386.      *
  387.      * The color scheme contained in the LOGPALETTE structure contains
  388.      * a number of colors where the first color is the suggested foreground,
  389.      * the second the suggested background, then the first HALF of those
  390.      * remaining are suggested fill colors and the last half suggested
  391.      * line colors.  If there are an odd number of colors, give the extra
  392.      * color to the fill colors, that is, there is one less line color than
  393.      * fill colors.
  394.      */
  395.  
  396.     return OLE_ERROR_PALETTE;
  397.     }
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404. /*
  405.  * ObjSetData
  406.  *
  407.  * Purpose:
  408.  *  Instructs the object to take the given data as current and copy it
  409.  *  to the object's internal data, use when a client opens an embedded
  410.  *  object or if the client calls OleSetData.
  411.  *
  412.  *  *NOTE: This function MUST be supported even if the registration
  413.  *         database does not contain an entry for SetDataFormats for
  414.  *         this server, because the callback is still used when opening
  415.  *         an embedded object for editing.
  416.  *
  417.  * Parameters:
  418.  *  pObj            LPSCHMOOOBJECT specifying the object affected.
  419.  *  cf              WORD format to return data in, may be "Native."
  420.  *  hData           HANDLE to global memory containing the data.
  421.  *
  422.  * Return Value:
  423.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  424.  */
  425.  
  426. OLESTATUS FAR PASCAL ObjSetData(LPSCHMOOOBJECT pObj, WORD cf, HANDLE hData)
  427.     {
  428.     LPPOLYLINE          lppl;
  429.  
  430.     /*
  431.      * 1.   If the data format is not supported, return OLE_ERROR_FORMAT.
  432.      * 2.   Attempt to GlobalLock the memory to get a pointer to the data.
  433.      *      If GlobalLock returns NULL, return OLE_ERROR_MEMORY.
  434.      * 3.   Copy the data to the object identified by pObj.
  435.      * 4.   Unlock and GlobalFree the data handle.  The ObjSetData method
  436.      *      is responsible for the memory.
  437.      * 5.   Return OLE_OK.
  438.      */
  439.  
  440.     //Check if we were given Native data.  We don't support anything else.
  441.     if (pOLE->cfNative!=cf)
  442.         return OLE_ERROR_FORMAT;
  443.  
  444.     lppl=(LPPOLYLINE)GlobalLock(hData);
  445.  
  446.     /*
  447.      * CHECK the return from GlobalLock since we don't know where this
  448.      * handle has been.
  449.      */
  450.     if (NULL==lppl)
  451.         return OLE_ERROR_MEMORY;
  452.  
  453.     //Set the data through the editing window.
  454.     SendMessage(pGlob->hWndPolyline, PLM_POLYLINESET, TRUE, (LONG)lppl);
  455.  
  456.     //Make sure we are not dirty--no updating is yet necessary.
  457.     FDirtySet(FALSE);
  458.  
  459.     //Server is responsible for freeing the data.
  460.     GlobalUnlock(hData);
  461.     GlobalFree(hData);
  462.     return OLE_OK;
  463.     }
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470. /*
  471.  * ObjSetTargetDevice
  472.  *
  473.  * Purpose:
  474.  *  Communicates information from the client application to the server
  475.  *  about the device on which the object is drawn.
  476.  *
  477.  * Parameters:
  478.  *  pObj            LPSCHMOOOBJECT specifying the object affected.
  479.  *  hData           HANDLE containing a STDTARGETDEVICE structure.
  480.  *
  481.  * Return Value:
  482.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  483.  */
  484.  
  485. OLESTATUS FAR PASCAL ObjSetTargetDevice(LPSCHMOOOBJECT pObj, HANDLE hData)
  486.     {
  487.  
  488.     /*
  489.      * The server is responsible for freeing the the data handle
  490.      * once it has finished using that data.
  491.      *
  492.      * If NULL==hData, then rendering is necessary for the screen.
  493.      */
  494.  
  495.     if (NULL!=hData)
  496.         GlobalFree(hData);
  497.  
  498.     return OLE_OK;
  499.     }
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507. /*
  508.  * ObjShow
  509.  *
  510.  * Purpose:
  511.  *  Causes the server to show an object, showing the window and
  512.  *  scrolling it's client area if necessary.
  513.  *
  514.  * Parameters:
  515.  *  pObj            LPSCHMOOOBJECT specifying the object affected.
  516.  *  fTakeFocus      BOOL:  TRUE if the server should get the focus,
  517.  *                  FALSE if not.
  518.  *
  519.  * Return Value:
  520.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  521.  */
  522.  
  523. OLESTATUS FAR PASCAL ObjShow(LPSCHMOOOBJECT pObj, BOOL fTakeFocus)
  524.     {
  525.     /*
  526.      * 1.   Show the application window(s) if not already visible.
  527.      * 2.   Scroll the object identified by pObj into view, if necessary.
  528.      * 3.   Select the object if possible.
  529.      * 4.   If fTakeFocus is TRUE, call SetFocus with the main window handle.
  530.      * 5.   Return OLE_OK if successful, OLE_ERROR_GENERIC otherwise.
  531.      */
  532.  
  533.     //Keep WM_SIZE on the ShowWindow from making us dirty.
  534.     pGlob->fNoDirty=TRUE;
  535.  
  536.     //Since we only have one object, we don't care what's in pObj.
  537.     ShowWindow(pGlob->hWnd, SW_NORMAL);
  538.  
  539.     pGlob->fNoDirty=FALSE;
  540.  
  541.     if (fTakeFocus)
  542.         SetFocus(pGlob->hWnd);
  543.  
  544.     return OLE_OK;
  545.     }
  546.  
  547.  
  548. #endif //MAKEOLESERVER
  549.